package com.uinnova.product.eam.web.sync;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Sets;
import com.uino.api.client.permission.IRoleApiSvc;
import com.uino.api.client.permission.IUserApiSvc;
import com.uino.bean.permission.base.SysRole;
import com.uino.bean.permission.business.UserInfo;
import com.uino.bean.permission.query.CSysUser;
import com.uino.dao.util.ESUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 同步太保用户数据信息
 *
 * @author lichong
 * @since 2022/9/7 17:01
 */
@Slf4j
@RestController
@RequestMapping("/sync/")
public class SyncUserMvc {

    @Autowired
    private IUserApiSvc userApiSvc;

    @Autowired
    private IRoleApiSvc roleApiSvc;

    @Value("${taibao.admin:系统管理员-架构模块}")
    private String taibaoAdmin;

    /**
     * 批量同步用户数据
     *
     * @return 同步结果
     */
    @PostMapping("syncUserDataBatchToEa")
    public HashMap<String, Object> syncUserDataBatch(@RequestBody List<TaiBaoUser> users) {

        log.info("同步太保用户数据,用户数量：{}", users.size());
        HashMap<String, Object> taibaoResult = new HashMap<>();
        AtomicInteger successNum = new AtomicInteger();
        AtomicInteger errorNum = new AtomicInteger();
        Set<String> errorUsers = new HashSet<>();
        for (TaiBaoUser user : users) {
            if (log.isDebugEnabled()) {
                log.debug("同步前太保用户数据：{}", JSON.toJSONString(user));
            }
            try {
                UserInfo userInfo = saveTaibaoUserToEa(user);
                if (log.isDebugEnabled()) {
                    log.debug("同步至ea后用户数据：{}", JSON.toJSONString(userInfo));
                }
                successNum.incrementAndGet();
            } catch (Exception e) {
                errorUsers.add(user.getUserName());
                errorNum.incrementAndGet();
                log.error("{}-用户保存异常：{}", user.getUserName(), e);
            }
        }
        taibaoResult.put("successNum", successNum);
        taibaoResult.put("errorNum", errorNum);
        taibaoResult.put("errorUsers", errorUsers);
        return taibaoResult;
    }

    /**
     * 保存并更新角色
     *
     * @param taiBaoUser
     */
    private UserInfo saveTaibaoUserToEa(TaiBaoUser taiBaoUser) {

        String userCode = taiBaoUser.getUserCode();
        CSysUser cSysUser = new CSysUser();
        cSysUser.setLoginCodeEqual(userCode);
        List<UserInfo> userInfoByCdt = userApiSvc.getUserInfoByCdt(cSysUser, true);
        UserInfo userInfo;
        if (CollectionUtils.isEmpty(userInfoByCdt)) {
            if (log.isDebugEnabled()) {
                log.debug("用户不存在需要新建用户");
            }
            //新建用户
            userInfo = new UserInfo();
            userInfo.setId(ESUtil.getUUID());
            userInfo.setUserName(taiBaoUser.getUserName());
            userInfo.setLoginCode(taiBaoUser.getUserCode());
            userInfo.setMobileNo(taiBaoUser.getMobileNo());
            userInfo.setEmailAdress(taiBaoUser.getEmailAdress());
            userInfo.setIcon("");
            userInfo.setDomainId(1L);
            userInfo.setLoginPasswd(DigestUtils.sha256Hex(userCode));
            userInfo.setCreator("TAIBAO_SYNC");
            userInfo.setSuperUserFlag(0);
            userInfo.setStatus(taiBaoUser.getStatus());
            userInfo.setLockFlag(0);
            userInfo.setTryTimes(0);
            userInfo.setLastLoginTime(System.currentTimeMillis());
            List<TaiBaoRole> fraRoleList = taiBaoUser.getFraRoleList();
            HashSet<String> roleNames = Sets.newHashSet();

            for (TaiBaoRole taiBaoRole : fraRoleList) {
                //太保'系统管理员-架构模块'角色对应admin
                String roleName = taiBaoRole.getOrgName() + "-" + taiBaoRole.getRoleName();
                if (taibaoAdmin.equals(roleName)) {
                    roleName = "admin";
                }
                roleNames.add(roleName);
            }
            if (log.isDebugEnabled()) {
                log.debug("太保角色：{}", roleNames);
            }
            BoolQueryBuilder must = QueryBuilders.boolQuery().must(QueryBuilders.termsQuery("roleName.keyword", roleNames));
            List<SysRole> sysRoles = roleApiSvc.getRolesByQuery(must);
            if (sysRoles != null && sysRoles.size() > 0) {
                userInfo.setRoles(new HashSet<>(sysRoles));
            }
            userApiSvc.saveOrUpdate(userInfo);
//            log.info("保存用户{}", JSON.toJSONString(userInfo));
        } else {
            userInfo = userInfoByCdt.get(0);
            Set<SysRole> roles = userInfo.getRoles();
            Set<String> eaRoleNames;
            if (CollectionUtils.isEmpty(roles)) {
                roles = new HashSet<>();
                eaRoleNames = new HashSet<>();
            } else {
                eaRoleNames = roles.stream().map(SysRole::getRoleName).collect(Collectors.toSet());
            }
            List<TaiBaoRole> fraRoleList = taiBaoUser.getFraRoleList();
            Set<String> taiBaoRoleNames = Sets.newHashSet();
            for (TaiBaoRole taiBaoRole : fraRoleList) {
                String roleName = taiBaoRole.getOrgName() + "-" + taiBaoRole.getRoleName();
                if (taibaoAdmin.equals(roleName)) {
                    roleName = "admin";
                }
                taiBaoRoleNames.add(roleName);
            }
            //获取相同角色
            Sets.SetView<String> someRoles = Sets.intersection(eaRoleNames, taiBaoRoleNames);
            //需要删除的角色
            Sets.SetView<String> deleteRoleName = Sets.difference(eaRoleNames, someRoles);
            //需要新增的角色
            Sets.SetView<String> addRoleName = Sets.difference(taiBaoRoleNames, someRoles);
            if (!CollectionUtils.isEmpty(deleteRoleName) || !CollectionUtils.isEmpty(addRoleName)) {
                if (log.isDebugEnabled()) {
                    log.debug("该用户角色不一致，开始修改角色：{},{}", userInfo.getUserName(), userInfo.getLoginCode());
                }
                if (!CollectionUtils.isEmpty(deleteRoleName)) {
                    roles.removeIf(r -> deleteRoleName.contains(r.getRoleName()));
                }
                if (!CollectionUtils.isEmpty(addRoleName)) {
                    BoolQueryBuilder must = QueryBuilders.boolQuery().must(QueryBuilders.termsQuery("roleName.keyword", addRoleName));
                    List<SysRole> sysRoles = roleApiSvc.getRolesByQuery(must);
                    roles.addAll(sysRoles);
                }
                userInfo.setRoles(roles);
                userApiSvc.saveOrUpdate(userInfo);
//                log.info("保存用户{}",JSON.toJSONString(userInfo));
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("改用户角色未改动,太保角色：{},ea角色：{}", taiBaoRoleNames, eaRoleNames);
                }
            }
        }
        return userInfo;
    }
}
